﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;

namespace ELearning.Common.Extensions
{
    /// <summary>
    /// 强制转化辅助类(无异常抛出)
    /// </summary>
    public static class ConvertHelper
    {
        #region 强制转化

        /// <summary>
        /// object转化为Bool类型
        /// </summary>
        public static bool ObjToBool(this object obj)
        {
            bool flag;
            if (obj == null)
            {
                return false;
            }
            if (obj.Equals(DBNull.Value))
            {
                return false;
            }
            return (bool.TryParse(obj.ToString(), out flag) && flag);
        }

        /// <summary>
        /// object强制转化为DateTime类型(吃掉异常)
        /// </summary>
        public static DateTime? ObjToDateNull(this object obj)
        {
            if (obj == null)
            {
                return null;
            }
            try
            {
                return Convert.ToDateTime(obj);
            }
            catch (ArgumentNullException ex)
            {
                return null;
            }
        }

        /// <summary>
        /// int强制转化
        /// </summary>
        public static int ObjToInt(this object obj)
        {
            if (obj != null)
            {
                int num;
                if (obj.Equals(DBNull.Value))
                {
                    return 0;
                }
                if (int.TryParse(obj.ToString(), out num))
                {
                    return num;
                }
            }
            return 0;
        }

        /// <summary>
        /// 强制转化为long
        /// </summary>
        public static long ObjToLong(this object obj)
        {
            if (obj != null)
            {
                long num;
                if (obj.Equals(DBNull.Value))
                {
                    return 0;
                }
                if (long.TryParse(obj.ToString(), out num))
                {
                    return num;
                }
            }
            return 0;
        }

        /// <summary>
        /// 强制转化可空int类型
        /// </summary>
        public static int? ObjToIntNull(this object obj)
        {
            if (obj == null)
            {
                return null;
            }
            if (obj.Equals(DBNull.Value))
            {
                return null;
            }
            return ObjToInt(obj);
        }

        /// <summary>
        /// 强制转化为string
        /// </summary>
        public static string ObjToStr(this object obj)
        {
            if (obj == null)
            {
                return "";
            }
            if (obj.Equals(DBNull.Value))
            {
                return "";
            }
            return Convert.ToString(obj);
        }

        /// <summary>
        /// Decimal转化
        /// </summary>
        public static decimal ObjToDecimal(this object obj)
        {
            if (obj == null)
            {
                return 0M;
            }
            if (obj.Equals(DBNull.Value))
            {
                return 0M;
            }
            try
            {
                return Convert.ToDecimal(obj);
            }
            catch
            {
                return 0M;
            }
        }

        /// <summary>
        /// Decimal可空类型转化
        /// </summary>
        public static decimal? ObjToDecimalNull(this object obj)
        {
            if (obj == null)
            {
                return null;
            }
            if (obj.Equals(DBNull.Value))
            {
                return null;
            }
            return ObjToDecimal(obj);
        }

        /// <summary>
        /// 
        /// </summary>
        public static string intArryToStr(List<int> intArry)
        {
            string[] str = intArry.Select(i => i.ToString()).ToArray();
            var nStr = string.Join(",", str);
            return nStr;
        }

        /// <summary>
        /// 
        /// </summary>
        public static string guidArryToStr(List<Guid> guidArry)
        {
            string[] str = guidArry.Select(i => i.ToString()).ToArray();
            var nStr = string.Join(",", str);
            return nStr;
        }
        #endregion

        /// <summary>
        /// DataTable转List
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static List<T> DtToList<T>(DataTable dt)
        {
            List<T> list = new List<T>();
            foreach (DataRow dr in dt.Rows)
            {
                T t = Activator.CreateInstance<T>();
                PropertyInfo[] properties = t.GetType().GetProperties();
                foreach (var item in properties)
                {
                    if (dt.Columns.Contains(item.Name))
                    {
                        object value = dr[item.Name];
                        if (value.ToString() != "")
                        {
                            item.SetValue(t, value.ToString(), null);
                        }
                    }
                }
                list.Add(t);
            }
            return list;
        }
        /// <summary>
        /// List转DataTable
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public static DataTable ToDataTable<T>(List<T> list)
        {
            DataTable dt = new DataTable();
            Type type = typeof(T);
            List<PropertyInfo> properties = new List<PropertyInfo>();
            Array.ForEach<PropertyInfo>(type.GetProperties(), p =>
            {
                properties.Add(p);
                dt.Columns.Add(p.Name, p.PropertyType);
            });
            foreach (var item in list)
            {
                DataRow row = dt.NewRow();
                properties.ForEach(p =>
                {
                    row[p.Name] = p.GetValue(item, null);
                });
                dt.Rows.Add(row);
            }
            return dt;
        }

        /// <summary>  
        /// 把一个一维数组转换为DataTable  
        /// </summary>  
        /// <param name="ColumnName">列名</param>  
        /// <param name="Array">一维数组</param>  
        /// <returns>返回DataTable</returns>  
        /// <remarks>柳永法 http://www.yongfa365.com/ </remarks>  
        public static DataTable ToDataTable(string ColumnName, string[] Array)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add(ColumnName, typeof(string));

            for (int i = 0; i < Array.Length; i++)
            {
                DataRow dr = dt.NewRow();
                dr[ColumnName] = Array[i].ToString();
                dt.Rows.Add(dr);
            }

            return dt;
        }

        /// <summary>  
        /// 把一个一维数组转换为DataTable  
        /// </summary>  
        /// <param name="ColumnName">列名</param>  
        /// <param name="Array">一维数组</param>  
        /// <returns>返回DataTable</returns>  
        /// <remarks>柳永法 http://www.yongfa365.com/ </remarks>  
        public static DataTable ToDataTable(string ColumnName, int[] Array, string tableName)
        {
            DataTable dt = new DataTable();
            dt.TableName = tableName;
            dt.Columns.Add(ColumnName, typeof(int));

            for (int i = 0; i < Array.Length; i++)
            {
                DataRow dr = dt.NewRow();
                dr[ColumnName] = Array[i];
                dt.Rows.Add(dr);
            }

            return dt;
        }


        /// <summary>  
        /// 把一个一维数组转换为DataTable  
        /// </summary>  
        /// <param name="ColumnName">列名</param>  
        /// <param name="Array">一维数组</param>  
        /// <returns>返回DataTable</returns>  
        /// <remarks>柳永法 http://www.yongfa365.com/ </remarks>  
        public static DataTable ToDataTable(string ColumnName, Guid[] Array, string tableName)
        {
            DataTable dt = new DataTable();
            dt.TableName = tableName;
            dt.Columns.Add(ColumnName, typeof(Guid));

            for (int i = 0; i < Array.Length; i++)
            {
                DataRow dr = dt.NewRow();
                dr[ColumnName] = Array[i];
                dt.Rows.Add(dr);
            }

            return dt;
        }

        /// <summary>
        /// 实现泛型集合到数组对象转换的静态扩展方法
        /// </summary>
        /// <typeparam name="T">泛型对象</typeparam>
        /// <param name="lines">泛型集合</param>
        /// <param name="lambdas">需要转换的泛型对象属性</param>
        /// <returns>数据对象</returns>
        public static object[,] To2DArray<T>(this List<T> lines, params Func<T, object>[] lambdas)
        {
            var array = new object[lines.Count(), lambdas.Count()];
            var lineCounter = 0;
            lines.ForEach(line =>
            {
                for (var i = 0; i < lambdas.Length; i++)
                {
                    array[lineCounter, i] = lambdas[i](line);
                }
                lineCounter++;
            });

            return array;
        }
    }

}
